package com.github.skystardust.lotteryex.gui.inventory;

import com.github.skystardust.lotteryex.utils.OptionalUtils;
import org.bukkit.Bukkit;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class LotteryInventory implements ConfigurationSerializable {
    private UUID uuid;
    private String title;
    private int inventorySize;
    private Inventory inventory;

    public LotteryInventory(UUID uuid, String title, int inventorySize) {
        this.uuid = uuid;
        this.title = title;
    }

    public LotteryInventory(String title, int inventorySize) {
        this.uuid = UUID.randomUUID();
        this.title = title;
        this.inventorySize = inventorySize;
    }

    public LotteryInventory(Map<String, Object> stringObjectMap) {
        this.uuid = UUID.fromString((String) stringObjectMap.get("uuid"));
        this.title = (String) stringObjectMap.get("title");
        this.inventorySize = (int) stringObjectMap.get("inventorySize");
        this.inventory = toInventory(null);
    }

    private LotteryInventory(Builder builder) {
        setUuid(builder.uuid);
        setTitle(builder.title);
        setInventorySize(builder.inventorySize);
    }

    public static Builder newBuilder() {
        return new Builder();
    }

    public UUID getUuid() {
        return uuid;
    }

    public void setUuid(UUID uuid) {
        this.uuid = uuid;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getInventorySize() {
        return inventorySize;
    }

    public void setInventorySize(int inventorySize) {
        this.inventorySize = inventorySize;
    }

    public Inventory getInventory() {
        return inventory;
    }

    public void setInventory(Inventory inventory) {
        this.inventory = inventory;
    }

    @Override
    public Map<String, Object> serialize() {
        return new OptionalUtils<>(() -> {
            HashMap<String, Object> stringObjectHashMap = new HashMap<>();
            stringObjectHashMap.put("title", title);
            stringObjectHashMap.put("inventorySize", inventorySize);
            return stringObjectHashMap;
        }).getOptional().orElseGet(HashMap::new);
    }

    public Inventory toInventory(@Nullable InventoryHolder inventoryHolder) {
        return inventory == null ? new OptionalUtils<>(() -> inventoryHolder)
                .map(owner -> Bukkit.createInventory(owner, inventorySize, title))
                .orElseGet(() -> Bukkit.createInventory(null, inventorySize, title)) : inventory;
    }

    public static final class Builder {
        private UUID uuid;
        private String title;
        private int inventorySize;

        private Builder() {
        }

        @Nonnull
        public Builder withUuid(@Nonnull UUID val) {
            uuid = val;
            return this;
        }

        @Nonnull
        public Builder withTitle(@Nonnull String val) {
            title = val;
            return this;
        }

        @Nonnull
        public Builder withInventorySize(int val) {
            inventorySize = val;
            return this;
        }

        @Nonnull
        public LotteryInventory build() {
            return new LotteryInventory(this);
        }
    }
}
